{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "d1f20875-c50d-46df-906b-49ec1d0c6002",
   "metadata": {},
   "source": [
    "## 10.9 AlexNet的实现\n"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "c90a18b9-d8e8-431c-856c-35f1e4ed05e1",
   "metadata": {},
   "source": [
    "### 1.任务描述\n",
    "\n",
    "使用TensorFlow实现AlexNet，对CIFAR-10数据集进行训练，实现多分类。"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "f5b4fc39-cbcf-432a-bf1e-e75e642d4b87",
   "metadata": {},
   "source": [
    "### 2.知识准备\n",
    "\n",
    "见教程。"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "55043130-4496-43a3-803b-9bc1cea8b1b8",
   "metadata": {},
   "source": [
    "### 3.任务分析\n",
    "\n",
    "定义一个AlexNet8的网络实现类，在该类中定义网络结构并定义表明参数传播方向的前向传播函数。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "435c6090-cfda-4f46-a550-22a368e41e4a",
   "metadata": {},
   "source": [
    "### 4.任务实施\n"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "ec75eb6c-5da3-467d-a471-ca3b47242dd6",
   "metadata": {},
   "source": [
    "执行代码"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "2ae9da58-e339-4d22-9f8d-ca255711d89e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 1/5\n",
      "1563/1563 [==============================] - 22s 12ms/step - loss: 1.5961 - sparse_categorical_accuracy: 0.4157 - val_loss: 1.9467 - val_sparse_categorical_accuracy: 0.3472\n",
      "Epoch 2/5\n",
      "1563/1563 [==============================] - 18s 12ms/step - loss: 1.2663 - sparse_categorical_accuracy: 0.5560 - val_loss: 1.2969 - val_sparse_categorical_accuracy: 0.5456\n",
      "Epoch 3/5\n",
      "1563/1563 [==============================] - 19s 12ms/step - loss: 1.1428 - sparse_categorical_accuracy: 0.6057 - val_loss: 1.8642 - val_sparse_categorical_accuracy: 0.4088\n",
      "Epoch 4/5\n",
      "1563/1563 [==============================] - 18s 12ms/step - loss: 1.0530 - sparse_categorical_accuracy: 0.6383 - val_loss: 1.1089 - val_sparse_categorical_accuracy: 0.6107\n",
      "Epoch 5/5\n",
      "1563/1563 [==============================] - 18s 12ms/step - loss: 0.9842 - sparse_categorical_accuracy: 0.6633 - val_loss: 1.1681 - val_sparse_categorical_accuracy: 0.5982\n",
      "Model: \"alex_net8\"\n",
      "_________________________________________________________________\n",
      " Layer (type)                Output Shape              Param #   \n",
      "=================================================================\n",
      " conv2d (Conv2D)             multiple                  2688      \n",
      "                                                                 \n",
      " batch_normalization (BatchN  multiple                 384       \n",
      " ormalization)                                                   \n",
      "                                                                 \n",
      " activation (Activation)     multiple                  0         \n",
      "                                                                 \n",
      " max_pooling2d (MaxPooling2D  multiple                 0         \n",
      " )                                                               \n",
      "                                                                 \n",
      " conv2d_1 (Conv2D)           multiple                  221440    \n",
      "                                                                 \n",
      " batch_normalization_1 (Batc  multiple                 1024      \n",
      " hNormalization)                                                 \n",
      "                                                                 \n",
      " activation_1 (Activation)   multiple                  0         \n",
      "                                                                 \n",
      " max_pooling2d_1 (MaxPooling  multiple                 0         \n",
      " 2D)                                                             \n",
      "                                                                 \n",
      " conv2d_2 (Conv2D)           multiple                  885120    \n",
      "                                                                 \n",
      " conv2d_3 (Conv2D)           multiple                  1327488   \n",
      "                                                                 \n",
      " conv2d_4 (Conv2D)           multiple                  884992    \n",
      "                                                                 \n",
      " max_pooling2d_2 (MaxPooling  multiple                 0         \n",
      " 2D)                                                             \n",
      "                                                                 \n",
      " flatten (Flatten)           multiple                  0         \n",
      "                                                                 \n",
      " dense (Dense)               multiple                  2099200   \n",
      "                                                                 \n",
      " dropout (Dropout)           multiple                  0         \n",
      "                                                                 \n",
      " dense_1 (Dense)             multiple                  4196352   \n",
      "                                                                 \n",
      " dropout_1 (Dropout)         multiple                  0         \n",
      "                                                                 \n",
      " dense_2 (Dense)             multiple                  20490     \n",
      "                                                                 \n",
      "=================================================================\n",
      "Total params: 9,639,178\n",
      "Trainable params: 9,638,474\n",
      "Non-trainable params: 704\n",
      "_________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "# 1，导入模块\n",
    "import tensorflow as tf\n",
    "from tensorflow.keras.layers import Conv2D, BatchNormalization, Activation, MaxPool2D, Dropout, Flatten, Dense\n",
    "from tensorflow.keras import Model\n",
    "# 2，加载数据集\n",
    "(x_train, y_train), (x_test, y_test) = tf.keras.datasets.cifar10.load_data()\n",
    "x_train, x_test = x_train / 255.0, x_test / 255.0\n",
    "\n",
    "# 3，创建网络\n",
    "class AlexNet8(Model):\n",
    "    def __init__(self):\n",
    "        super(AlexNet8,self).__init__()\n",
    "        # 第1个卷积层\n",
    "        self.c1 = Conv2D(filters=96, kernel_size=(3, 3))\n",
    "        self.b1 = BatchNormalization()\n",
    "        self.a1 = Activation('relu')\n",
    "        self.p1 = MaxPool2D(pool_size=(3, 3), strides=2)        \n",
    "        # 第2个卷积层\n",
    "        self.c2 = Conv2D(filters=256, kernel_size=(3, 3))\n",
    "        self.b2 = BatchNormalization()\n",
    "        self.a2 = Activation('relu')\n",
    "        self.p2 = MaxPool2D(pool_size=(3, 3), strides=2)        \n",
    "        # 第3个卷积层\n",
    "        self.c3 = Conv2D(filters=384, kernel_size=(3, 3), padding='same',activation='relu')\n",
    "        # 第4个卷积层                 \n",
    "        self.c4 = Conv2D(filters=384, kernel_size=(3, 3), padding='same',activation='relu')\n",
    "        # 第5个卷积层                 \n",
    "        self.c5 = Conv2D(filters=256, kernel_size=(3, 3), padding='same',activation='relu')        \n",
    "        # 池化层\n",
    "        self.p3 = MaxPool2D(pool_size=(3, 3), strides=2)\n",
    "        # 拉平层\n",
    "        self.flatten = Flatten()        \n",
    "        # 全连接层\n",
    "        self.f1 = Dense(2048, activation='relu')\n",
    "        self.d1 = Dropout(0.5)\n",
    "        self.f2 = Dense(2048, activation='relu')\n",
    "        self.d2 = Dropout(0.5)\n",
    "        # 输出层\n",
    "        self.f3 = Dense(10, activation='softmax')        \n",
    "    def call(self,x):\n",
    "        x = self.c1(x)\n",
    "        x = self.b1(x)\n",
    "        x = self.a1(x)\n",
    "        x = self.p1(x)\n",
    "        x = self.c2(x)\n",
    "        x = self.b2(x)\n",
    "        x = self.a2(x)\n",
    "        x = self.p2(x)\n",
    "        x = self.c3(x)\n",
    "        x = self.c4(x)\n",
    "        x = self.c5(x)\n",
    "        x = self.p3(x)\n",
    "        x = self.flatten(x)\n",
    "        x = self.f1(x)\n",
    "        x = self.d1(x)\n",
    "        x = self.f2(x)\n",
    "        x = self.d2(x)\n",
    "        y = self.f3(x)\n",
    "        return y\n",
    "# 4，配置网络\n",
    "model = AlexNet8()\n",
    "# 配置网络\n",
    "model.compile(\n",
    "    # 优化器\n",
    "    optimizer='adam',\n",
    "    # 损失函数\n",
    "    loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits= False),\n",
    "    # 评测方法\n",
    "    metrics=['sparse_categorical_accuracy']\n",
    ")\n",
    "# 5，训练网络\n",
    "model.fit(\n",
    "    x_train, y_train, batch_size=32, epochs=5, \n",
    "    validation_data=(x_test, y_test), validation_freq=1)\n",
    "model.summary()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e6044c99-0741-4378-b2b6-f60c293cc3a9",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
